package com.tangpian.sna.core.analysis.svm;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.tangpian.sna.core.analysis.Analyzer;
import com.tangpian.sna.core.analysis.svm.algorithm.svm_predict;
import com.tangpian.sna.core.analysis.svm.algorithm.svm_train;
import com.tangpian.sna.core.analysis.svm.dao.ClassificationDao;
import com.tangpian.sna.core.analysis.svm.dao.ItemClassificationDao;
import com.tangpian.sna.core.analysis.svm.model.Classification;
import com.tangpian.sna.core.analysis.svm.model.ItemClassification;
import com.tangpian.sna.core.analysis.svm.pre.TextVectorBuilder;
import com.tangpian.sna.core.model.Item;
import com.tangpian.sna.core.util.FileUtil;

@Component
public class SvmAnalyzer<T extends Item> implements Analyzer<T> {
	private Logger logger = LoggerFactory.getLogger(SvmAnalyzer.class);

	private static final String trainPath = "res/svm/";

	@Autowired
	private ClassificationDao classificationDao;

	@Autowired
	private ItemClassificationDao itemClassificationDao;

	@Override
	public void analysis(List<T> items, String taskId) {
		logger.info("start SVM process……");
		SvmResult result = process(items, taskId);
		classificationDao.save(result.getClassifications());
		itemClassificationDao.save(result.getItemClassifications());
	}

	public SvmResult process(List<T> items, String taskId) {
		// String testPath = "";
		//
		String testOutputPath = FileUtil.getTempDir() + "/test.vector";
		String trainOutputPath = FileUtil.getTempDir() + "/train.vector";
		String modelFilePath = FileUtil.getTempDir() + "/train.model";
		String svmResult = FileUtil.getTempDir() + "result.txt";

		// read train file
		File trainDir = new File(FileUtil.getFilePathFromClasspath(trainPath));
		String[] types = trainDir.list();
		List<String>[] trainDatas = new List[types.length];
		List<Classification> classifications = new ArrayList<Classification>();
		for (int i = 0; i < types.length; i++) {
			trainDatas[i] = FileUtil.read(trainDir.getAbsolutePath()
					+ File.separator + types[i], "utf-8");
			Classification classification = new Classification();
			classification.setTaskId(taskId);
			classification.setId(i);
			classification.setName(types[i]);
			classifications.add(classification);
		}

		// read test file
		// List<String> testDatas = FileReader.read(testPath, "utf-8");

		List<String> testDatas = new ArrayList<String>();
		for (T item : items) {
			testDatas.add(item.getContent());
		}

		// build vector file
		logger.info("build vector file……");
		TextVectorBuilder builder = new TextVectorBuilder();
		builder.createTrainVectorFile(trainDatas, trainOutputPath);
		builder.createTestVectorFile(testDatas, testOutputPath);

		// lda process

		try {
			String[] trainArgs = { "-s", "1", "-t", "2", trainOutputPath,
					modelFilePath };
			logger.info("training……");
			String modelFile = svm_train.main(trainArgs);
			String[] testArgs = { testOutputPath, modelFile, svmResult };
			logger.info("testing……");
			svm_predict.main(testArgs);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// lda result
		List<String> lines = FileUtil.readFile(svmResult, "utf-8");
		List<ItemClassification> itemClassifications = new ArrayList<ItemClassification>();
		int i = 0;
		for (String string : lines) {
			ItemClassification e = new ItemClassification();
			e.setTaskId(taskId);
			e.setItemId(items.get(i).getId());
			e.setClassificationId((int) Double.parseDouble(string));
			itemClassifications.add(e);
			i++;
		}

		return new SvmResult(classifications, itemClassifications);
	}

}
